
<template>
  <div class="biz-chat">
    
    <biz-float-icon
      :x="x"
      :y="y"
      :topSafeArea="topSafeArea"
      :leftSafeArea="leftSafeArea"
      @updateX="updateX"
      @updateY="updateY"
      @dragend="onDragend"
      @click="openDrawer"
    >
      <div
        class="biz-chat-btn"
        type="primary"
      >
        <div class="biz-chat-btn-img-block">
          <img :src="xiaoBaoIcon" alt="小宝AI">
        </div>
      </div>
    </biz-float-icon>
    
    <el-drawer
      :modal="false"
      :wrapperClosable="true"
      custom-class="biz-chat-recommend-drawer"
      append-to-body
      size="460px"
      direction="rtl"
      ref="ElDrawer"
      :visible="visible"
      @close="closeDrawer"
      @open="onOpenHandler"
    > 
      
      <div class="biz-chat-panel-header-content">
        <header-app
          v-if="isShowAppService"
          @close="closeElementDrawer"
          @back="onBackHandler"
        />
        <biz-chat-panel-header
          v-else
          @close="closeElementDrawer"
        />
      </div>
      
      <div class="biz-chat-panel-content">
        
        <app
          ref="AppServiceView"
          v-show="isShowAppService"
          :currentApp="currentApp"
          :list="gptRobotAppList"
          @cancel="onCancelHandler"
          @confirm="onConfirmHandler"
        />
        
        <chat
          v-if="isFinishInit"
          v-show="!isShowAppService"
          ref="ChatView" 
          :stream="stream"
          :tenantId="tenantId" 
          :robotId="robotId"
          :currentApp="currentApp"
          @appTag="onAppTagClickHandler"
        />
        
      </div>
      
    </el-drawer>
    
  </div>
</template>

<script>
import { provide,ref } from 'vue'
/* component */
import chat from '@src/component/business/BizChatPanel/chat'
import BizChatPanelHeader from '@src/component/business/BizChatPanel/header'
import headerApp from '@src/component/business/BizChatPanel/header-app'
import app from '@src/component/business/BizChatPanel/app'
import BizFloatIcon from '@src/component/business/BizFloatIcon'
/* hooks */
import { useFetchSettingGPTRobotAppList } from '@gpt/hooks'
/* model */
import { SettingGPTServiceTypeEnum } from '@gpt/model'
/* model */
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
/* enum */
import StorageModuleEnum from '@model/enum/StorageModuleEnum'
/* util */
import { getRootWindowInitData } from '@src/util/window'
import { getLocalesOssUrl, getOssUrl } from '@src/util/assets'
import { isFalsy } from 'pub-bbx-utils'
import { parse_with_default_value } from '@src/util/lang/object'
import { storageGet, storageSet } from '@src/util/storage.ts'
import _ from 'lodash'

const xiaoBaoIcon = getLocalesOssUrl('xiao-bao-animation.gif')

export default {
  name: 'biz-chat-panel',
  components: {
    chat,
    BizFloatIcon,
    headerApp,
    app,
    [BizChatPanelHeader.name]: BizChatPanelHeader
  },
  props: {
    tenantId: {
      type: String,
      default: ''
    },
    gptRobot: {
      type: Object,
      default: () => {}
    },
    navCollapse: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    
    const {
      loading,
      chatRobotAppList: gptRobotAppList,
      fetchGptRobotAppList
    } = useFetchSettingGPTRobotAppList()
    
    // fix 关闭对话再拖动页面，让对话图表重新渲染，层级太深，故此用provide
    const echartOpenChangeCount = ref(1)
    provide('echartOpenChange', echartOpenChangeCount)
    
    const onfetchGptRobotAppListHandler = async (robotId) => {
      return fetchGptRobotAppList({
        robotId
      })
    }
    
    return {
      loading,
      gptRobotAppList,
      onfetchGptRobotAppListHandler,
      echartOpenChangeCount
    }
    
  },
  data() {
    return {
      visible: false,
      xiaoBaoIcon,
      x: 0,
      y: 0,
      xDifference: 0,
      yDifference: 0,
      needInitChat: false,
      isShowAppService: false,
      currentApp: null,
      isFinishInit: false
    }
  },
  computed: {
    leftSafeArea() {
      return this.navCollapse ? 50 : 185
    },
    topSafeArea() {
      return 50
    },
    robotId() {
      return String(this.gptRobot.id)
    },
    robotSetting() {
      return parse_with_default_value(this.gptRobot?.setting, {})
    },
    stream() {
      return Boolean(this.robotSetting?.stream)
    },
    chatViewIndexComponent() {
      return this.$refs.ChatView || {}
    },
    chatViewViewComponent() {
      return this.chatViewIndexComponent?.$refs?.ChatAIView || {}
    },
    chatAIMessageListElement() {
      return this.chatViewViewComponent?.chatAIMessageListElement || {}
    }
  },
  watch: {
    visible(value) {
      if (isFalsy(value)) {
        this.saveChatAIMessageListElementScroll()
      } else {
        this.initChatAIMessageListElementScroll()
      }
    }
  },
  mounted() {
    this.initFloatIconPosition()
    this.initRobotApp().then(() => {
      this.isFinishInit = true
    })
    this.addResizeListener()
  },
  beforeMount() {
    this.removeResizeListener()
  },
  methods: {
    addResizeListener() {
      window.addEventListener('resize', this.initFloatIconPositionBaseDebounce)
    },
    removeResizeListener() {
      window.removeEventListener('resize', this.initFloatIconPositionBaseDebounce)
    },
    async outsideInit() {
      
      await this.initRobotApp()
      
      // 如果类型为BI，不初始化请求
      if (this.currentApp?.type === SettingGPTServiceTypeEnum.BI) {
        return
      }
      
      this.init()
      this.initChat()
    },
    async initRobotApp() {
      
      await this.onfetchGptRobotAppListHandler(this.robotId)
      
      const appType = await this.getAppTypeByStorage()
      
      this.currentApp = this.gptRobotAppList.find(item => {
        return item.type == appType
      })
      
      if (isFalsy(this.currentApp)) {
        this.currentApp = this.gptRobotAppList.find(item => {
          return item.type == SettingGPTServiceTypeEnum.Intelligent
        })
      }
      
      if (isFalsy(this.currentApp)) {
        this.currentApp = this.gptRobotAppList.find(item => {
          return item.type == SettingGPTServiceTypeEnum.Common
        })
      }
      
    },
    getAppTypeByStorage() {
      return storageGet(StorageKeyEnum.ChatAppType, SettingGPTServiceTypeEnum.Intelligent, StorageModuleEnum.AI)
    },
    setAppTypeByStorage(type) {
      storageSet(StorageKeyEnum.ChatAppType, type, StorageModuleEnum.AI)
    },
    init() {
      this.$refs.ChatView.init()
    },
    initWithChangeApp() {
      this.$refs.ChatView.initWithChangeApp()
    },
    initFloatIconPosition() {
      
      const x = localStorage.getItem(StorageKeyEnum.CHAT_PANEL_X)
      const y = localStorage.getItem(StorageKeyEnum.CHAT_PANEL_Y)
      const clientWidth = document.documentElement.clientWidth
      const clientHeight = document.documentElement.clientHeight
      
      if (x && y) {
        this.x = Number(x)
        this.y = Number(y)
        this.xDifference = clientWidth - this.x
        this.yDifference = clientHeight - this.y
        return
      }
      
      
      this.x = clientWidth - 130
      this.y = clientHeight - 130
      this.xDifference = clientWidth - this.x
      this.yDifference = clientHeight - this.y
      
    },
    initFloatIconPositionBase() {
      
      const clientWidth = document.documentElement.clientWidth
      const clientHeight = document.documentElement.clientHeight
      
      const x = clientWidth - this.xDifference
      const y = clientHeight - this.yDifference
      
      this.x = x
      this.y = y
      
    },
    initFloatIconPositionBaseDebounce: _.debounce(function() {
      this.initFloatIconPositionBase()
    }, 500),
    initChat() {
      
    },
    closeDrawer() {
      this.visible = false
    },
    openDrawer() {      
      this.visible = true
      this.echartOpenChangeCount += 1 // 打开drawer重新渲染已存在的图表用计数器来重绘组件图表
    },
    closeElementDrawer() {
      this.$refs.ElDrawer.closeDrawer()
    },
    initChatAIMessageListElementScroll() {
      this.$nextTick(() => {
        this.chatAIMessageListElement.scrollTop = this.chatAIMessageListElement.scrollHeight
      })
    },
    saveChatAIMessageListElementScroll() {
      
    },
    updateX(value) {
      const clientWidth = document.documentElement.clientWidth
      this.x = value
      this.xDifference = clientWidth - this.x
    },
    updateY(value) {
      const clientHeight = document.documentElement.clientHeight
      this.y = value
      this.yDifference = clientHeight - this.y
    },
    /** 
     * @description 拖动结束
     * 1. 保存当前元素的 X 坐标
     * 2. 保存当前元素的 Y 坐标
    */
    onDragend() {
      // 如果需要将坐标保存到 localStorage 中，那么就打开下面的注释
      // localStorage.setItem(StorageKeyEnum.CHAT_PANEL_X, this.x)
      // localStorage.setItem(StorageKeyEnum.CHAT_PANEL_Y, this.y)
    },
    onOpenHandler() {
      
      if (this.needInitChat) {
        this.initChat()
        this.needInitChat = false
      }
      
    },
    onAppTagClickHandler() {
      this.isShowAppService = true
    },
    onBackHandler() {
      this.isShowAppService = false
    },
    onCancelHandler() {
      this.onBackHandler()
      this.$refs.AppServiceView.resetValue()
    },
    onConfirmHandler(type) {
      
      this.onBackHandler()
      
      this.currentApp = this.gptRobotAppList.find(item => {
        return item.type == type
      })
      
      this.setAppTypeByStorage(type)
      
      // 如果类型为BI，不初始化请求
      if (type === SettingGPTServiceTypeEnum.BI) {
        return
      }
      
      this.initWithChangeApp()
      this.initChat()
      
    }
  }
}
</script>

<style lang="scss">

.biz-chat {
  position: fixed;
  right: 24px;
  bottom: 32px;
}

.biz-chat-btn {
  cursor: pointer;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  // box-shadow: 0px 0px 20px $color-primary-light-6;
  padding: 0 !important;
  background-color: none;
  
  i {
    font-size: 30px !important;
  }
  
}

.biz-chat-btn-img-block {
  height: 60px;
  width: 60px;
  border-radius: 50%;
  overflow: hidden;
  img {
    width: 100%;
    height: 100%;
  }
}

.biz-chat-recommend-drawer {
  .el-drawer {
    box-shadow: 0 8px 8px -5px rgba(0,0,0,.2), 0 8px 8px 2px rgba(0,0,0,.04), 0 4px 8px 5px rgba(0,0,0,.01); 
  }
  .biz-chat-panel-content {
    background-color: #f1f4fe;
  }
  .el-drawer__header {
    display: none;
  }
  .el-drawer__body {
    display: flex;
    flex-direction: column;
  }
  .biz-chat-panel-content {
    flex: 1;
    overflow: hidden;
  }
}
</style>